<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <style>
        .container {
            width: 1200px;
            margin: 0 auto;
            position: relative;
        }

        .image-item {
            position: absolute;
            top: 0;
            background-color: cadetblue;
        }

        .image-item img {
            width: 100%;
            vertical-align: top;
        }
    </style>
</head>

<body>
    <div class="container"></div>

    <script src="./utils/jquery-3.4.1.min.js"></script>
    <script src="./utils/mock-min.js"></script>
    <script src="./utils/server.js"></script>
    <script src="./utils/utils.js"></script>

    <script>
        // 获取图片列表显示区域的宽度
        const contentWidth = $('.container').width();
        // 设置图片显示的列数
        let column = 5;
        // 设置图片之间的边距
        const margin = 10;
        // 计算图片的宽度
        const imageWidth = (contentWidth - margin * (column - 1)) / column;

        // 功能一：将页面的静态图片全部替换成动态的数据
        let imagesData = {
            start: 0,    // 从第0张开始获取图片
            count: 20,   // 获取图片的张数
            rows: []     // 保存图片信息
        }

        const columnInfo = [];
        let firstShow = false;  // 记录第一行是否渲染完成

        // 1. 通过 ajax 获取数据库中的数据
        getImagesData();
        function getImagesData() {
            $.ajax({
                url: '/images/getImages',
                type: 'get',
                data: {
                    start: imagesData.start,
                    count: imagesData.count
                },
                dataType: 'json',
                success(msg) {
                    // console.log('请求结果', msg);
                    imagesData = msg;
                    render();
                }
            })
        }

        function render() {
            imagesData.rows.forEach((item, index) => {
                const imageHeight = imageWidth / item.width * item.height;
                // 渲染第一行图片
                if (index < column && !firstShow) {
                    $('.container').append(`
                        <div class="image-item" style="width:${imageWidth}px;height:${imageHeight}px;left:${index * (imageWidth + margin)}px">
                            <img data-src="${item.url}" alt=""/>    
                        </div>
                    `);
                    columnInfo.push({ columnHeight: imageHeight + margin, columnIndex: index });
                } else {
                    firstShow = true;
                    // 找到高度最低的一列
                    const { columnHeight, columnIndex } = columnInfo.sort((a, b) => a.columnHeight - b.columnHeight)[0];
                    $('.container').append(`
                        <div class="image-item" style="width:${imageWidth}px;height:${imageHeight}px;left:${columnIndex * (imageWidth + margin)}px;top:${columnHeight}px">
                            <img data-src="${item.url}" alt=""/>    
                        </div>
                    `);
                    columnInfo[0].columnHeight += imageHeight + margin;
                }
            })
            showImages();
        }

        // 功能二：滚动条触底后加载更多的图片
        $(window).scroll(function () {
            showImages();
            // 页面的高度
            const pageHeight = $(document).height();
            // 可视区高度
            const windowHeight = $(window).height();
            // 滚动条距离顶部的高度
            const scrollTop = $(window).scrollTop();
            if (pageHeight - windowHeight - scrollTop <= 200) {
                // 加载更多
                imagesData.start += imagesData.count;
                getImagesData();
            }
        })

        // 功能三：图片懒加载
        function showImages() {
            // 可视区高度
            const windowHeight = $(window).height();
            // 滚动条距离顶部的高度
            const scrollTop = $(window).scrollTop();
            $('.image-item img').each(function () {
                const imageTop = $(this).offset().top;
                if (imageTop - scrollTop < windowHeight) {
                    $(this).attr('src', $(this).data('src'));
                }
            })
        }
    </script>
</body>

</html>